#include "test_ble.h"
#include "cm_uart.h"
#include "cm_demo_uart.h"
/* Case返回枚举常量(或宏)名称字符串 */
#define TEST_MACRO_NAME_CASE(eMacro) case eMacro: return #eMacro
static uint32_t test_ble_client_flg = 0;//初始化为client端

static const char* test_ble_event_code_name(cm_ble_event_type_e event)
{
	switch (event)
	{
		TEST_MACRO_NAME_CASE(CM_BLE_EVENT_GAP_CONN);
		TEST_MACRO_NAME_CASE(CM_BLE_EVENT_GAP_CONN_PARAM_UPDATE);
		TEST_MACRO_NAME_CASE(CM_BLE_EVENT_SCAN_RESULT);
		TEST_MACRO_NAME_CASE(CM_BLE_EVENT_ADV_RESULT);
		TEST_MACRO_NAME_CASE(CM_BLE_EVENT_GATTS_READ);
		TEST_MACRO_NAME_CASE(CM_BLE_EVENT_GATTS_WRITE);
		TEST_MACRO_NAME_CASE(CM_BLE_EVENT_GATTC_NOTIFY);
		TEST_MACRO_NAME_CASE(CM_BLE_EVENT_GATTC_IND);
		TEST_MACRO_NAME_CASE(CM_BLE_EVENT_GATTC_SERVICE);
		TEST_MACRO_NAME_CASE(CM_BLE_EVENT_GATTC_CHARACTER);
		TEST_MACRO_NAME_CASE(CM_BLE_EVENT_GATTC_DESCRIPTOR);
		TEST_MACRO_NAME_CASE(CM_BLE_EVENT_GATTC_READ);
		TEST_MACRO_NAME_CASE(CM_BLE_EVENT_GATTC_WRITE);
		default:
			break;
	}
	return "Unknown event code";
}

static void __cm_ble_hex_to_str(const uint8_t *hex, uint8_t *str, const uint16_t hexSize)
{
	uint16_t hexIndex;
	for (hexIndex = 0; hexIndex < hexSize; hexIndex++) 
	{
		uint8_t lowVal = hex[hexIndex] % 16;				 
		uint8_t hiVal = (hex[hexIndex] / 16) % 16;			   
		str[2 * hexIndex] = (hiVal < 10) ? (hiVal + '0') : (hiVal + 'A' - 10); 
		str[2 * hexIndex + 1] = (lowVal < 10) ?  (lowVal + '0') : (lowVal + 'A' - 10); 
	}
	str[2 * hexIndex] = '\0';	 
}

static void test_ble_event_callback(cm_ble_event_type_e event, void *param)
{
	cm_demo_printf("[BT_DEMO] in %s() : event:[%s],", __func__,test_ble_event_code_name(event));

	switch(event)
	{
		case CM_BLE_EVENT_GAP_CONN: //连接状态事件 
		{
			cm_ble_event_conn_t *pevent_conn = (cm_ble_event_conn_t *)param; 

			cm_demo_printf("%d,%d,%d,%02X:%02X:%02X:%02X:%02X:%02X\n\n", pevent_conn->conn_index,pevent_conn->conn_status,pevent_conn->conn_reason,
				pevent_conn->conn_peeaddr.addr[0],pevent_conn->conn_peeaddr.addr[1],pevent_conn->conn_peeaddr.addr[2],pevent_conn->conn_peeaddr.addr[3],pevent_conn->conn_peeaddr.addr[4],pevent_conn->conn_peeaddr.addr[5]);
			if(!pevent_conn->conn_status && test_ble_client_flg) cm_ble_deinit();
			break;
		}
		case CM_BLE_EVENT_GAP_CONN_PARAM_UPDATE://连接参数更新
		{
			cm_ble_event_param_t *pevent_param= (cm_ble_event_param_t *)param; 
			cm_demo_printf("%d,%d,%d,%d\n\n", pevent_param->param_index,pevent_param->param_interval,pevent_param->param_latency,pevent_param->param_timeout);
			break;
		}
		case CM_BLE_EVENT_SCAN_RESULT: //BLE扫描结果
		{
			char rawdata_str[128] = {0};
			cm_ble_scan_result_t *pscan_result =(cm_ble_scan_result_t *)param;

			__cm_ble_hex_to_str((const uint8_t *)pscan_result->adv_data, (uint8_t *)rawdata_str, pscan_result->adv_len);
			
			cm_demo_printf("0,%02X:%02X:%02X:%02X:%02X:%02X,%d,%d,%d,%d,%s\n\n", pscan_result->con_addr.addr[0],pscan_result->con_addr.addr[1],pscan_result->con_addr.addr[2],pscan_result->con_addr.addr[3],pscan_result->con_addr.addr[4],pscan_result->con_addr.addr[5],
				pscan_result->con_addr.type,pscan_result->adv_type,pscan_result->rssi,pscan_result->adv_len,rawdata_str);
			break;
		}
		case CM_BLE_EVENT_ADV_RESULT://广播结果内容
		{
			cm_ble_adv_result_t *padv_result= (cm_ble_adv_result_t *)param; 
			cm_demo_printf("%d,%d\n\n", padv_result->adv_result,padv_result->adv_state);
			
			break;
		}
		case CM_BLE_EVENT_GATTS_READ://读取属性值事件
		{
			cm_ble_event_gatts_read_t *pevent_gatts_read = (cm_ble_event_gatts_read_t *)param; 

			cm_demo_printf("%d,%d,%d,%d\n\n", 
				pevent_gatts_read->gatt_index,
				pevent_gatts_read->gatt_srvid,
				pevent_gatts_read->gatt_charid,
				pevent_gatts_read->gatt_desid);
			
			break;
		}
		case CM_BLE_EVENT_GATTS_WRITE:
		{
			char rawdata_str[CM_BLE_DATA_LEN_MAX] = {0};
			
			cm_ble_event_gatts_write_t *pevent_gatts_write = (cm_ble_event_gatts_write_t *)param; 
			
			__cm_ble_hex_to_str((const uint8_t *)pevent_gatts_write->gatt_data, (uint8_t *)rawdata_str, pevent_gatts_write->gatt_len);	

			cm_demo_printf("%d,%d,%d,%d,%d,%s\n\n", 
				pevent_gatts_write->gatt_index,
				pevent_gatts_write->gatt_srvid,
				pevent_gatts_write->gatt_charid,
				pevent_gatts_write->gatt_desid,
				pevent_gatts_write->gatt_len,
				rawdata_str);	
	
			break;
		}
		case CM_BLE_EVENT_GATTC_NOTIFY://BLE通知属性值事件
		{
			char rawdata_str[CM_BLE_DATA_LEN_MAX] = {0};
			cm_ble_event_gattc_t *pevent_gattc_notify =(cm_ble_event_gattc_t *)param;
			
			__cm_ble_hex_to_str((const uint8_t *)pevent_gattc_notify->gatt_data, (uint8_t *)rawdata_str, pevent_gattc_notify->gatt_len);			

			cm_demo_printf("%d,%d,%d,%d,%s\n\n", 
				pevent_gattc_notify->gatt_index,
				pevent_gattc_notify->gatt_srvid,
				pevent_gattc_notify->gatt_charid,
				pevent_gattc_notify->gatt_len,
				rawdata_str);	
			break;
		}
		case CM_BLE_EVENT_GATTC_IND://BLE指示属性值事件
		{			
			char rawdata_str[CM_BLE_DATA_LEN_MAX] = {0};
			cm_ble_event_gattc_t *pevent_gattc_ind =(cm_ble_event_gattc_t *)param;
			
			__cm_ble_hex_to_str((const uint8_t *)pevent_gattc_ind->gatt_data, (uint8_t *)rawdata_str, pevent_gattc_ind->gatt_len);			

			cm_demo_printf("%d,%d,%d,%d,%s\n\n", 
				pevent_gattc_ind->gatt_index,
				pevent_gattc_ind->gatt_srvid,
				pevent_gattc_ind->gatt_charid,
				pevent_gattc_ind->gatt_len,
				rawdata_str);	

			break;
		}
		case CM_BLE_EVENT_GATTC_SERVICE://发现基本服务
		{
			cm_ble_event_service_t *pevent_service =(cm_ble_event_service_t *)param;
			cm_demo_printf("%d,%d,%d,%02X%02X\n\n", pevent_service->gatt_index,pevent_service->gatt_result,pevent_service->gatt_srvid,pevent_service->srvUuid.uuid[0],pevent_service->srvUuid.uuid[1]);
			break;	
		}
		case CM_BLE_EVENT_GATTC_CHARACTER://发现服务特征
		{
			cm_ble_event_gattc_character_t * pevent_gattc_character =(cm_ble_event_gattc_character_t *)param;
			
			cm_demo_printf("%d,%d,%d,%d,%02X%02X,%d\n\n", 
				pevent_gattc_character->gatt_index,
				pevent_gattc_character->gatt_srvid,	
				pevent_gattc_character->gatt_result,	
				pevent_gattc_character->gatt_chrid,				
				pevent_gattc_character->chr_uuid.uuid[0],pevent_gattc_character->chr_uuid.uuid[1],
				pevent_gattc_character->chr_permission);
			break;
		}
		case CM_BLE_EVENT_GATTC_DESCRIPTOR://发现服务特征描述符
		{
			cm_ble_event_gattc_descriptor_t * pevent_gattc_descriptor =(cm_ble_event_gattc_descriptor_t *)param;
			cm_demo_printf("%d,%d,%d,%d,%d,%02X%02X\n\n", 
				pevent_gattc_descriptor->gatt_index,
				pevent_gattc_descriptor->gatt_srvid,
				pevent_gattc_descriptor->gatt_chrid,	
				pevent_gattc_descriptor->gatt_result,	
				pevent_gattc_descriptor->gatt_desid,
				pevent_gattc_descriptor->des_uuid.uuid[0],pevent_gattc_descriptor->des_uuid.uuid[1]);
			break;
		}
		case CM_BLE_EVENT_GATTC_READ://读取服务特征值
		{
			char rawdata_str[CM_BLE_DATA_LEN_MAX] = {0};

			cm_ble_event_gattc_read_t * pevent_gattc_read =(cm_ble_event_gattc_read_t *)param;
			
			__cm_ble_hex_to_str((const uint8_t *)pevent_gattc_read->gatt_data, (uint8_t *)rawdata_str, pevent_gattc_read->gatt_len);
			cm_demo_printf("%d,%d,%d,%s\n\n", 
				pevent_gattc_read->gatt_index,
				pevent_gattc_read->gatt_result,
				pevent_gattc_read->gatt_len,	
				rawdata_str);
			
			break;
		}
		case CM_BLE_EVENT_GATTC_WRITE: //写服务特征值或特征描述符值
		{
			cm_ble_event_gattc_write_t * pevent_gattc_write =(cm_ble_event_gattc_write_t *)param;
	
			cm_demo_printf("%d,%d\n\n", pevent_gattc_write->gatt_index,pevent_gattc_write->gatt_result);
			
			break;
		}
		default:
			break;
	}

	return;
}

void cm_test_ble_operation(unsigned char *cmd[],int len)
{
	if(0 == strcmp("INIT",cmd[2]))
	{
		cm_ble_mode_e mode = atoi(cmd[3]);
		int32_t ret = cm_ble_init(mode,test_ble_event_callback);//初始化ble，打开BLE协议栈并注册BLE事件回调处理函数
		cm_demo_printf("cm_ble_init ret:%d",ret);
		OCTEST_FUNC_EXPECT_EQUAL_INT32(0,ret,cm_ble_init);
		if(0 != ret )
		{
			cm_demo_printf("ble cm_ble_init ret:%d,init fail\n",ret);
			cm_demo_printf("ble cm_ble_deinit ret:%d\n", cm_ble_deinit());
		}

	}else if(0 == strcmp("DEINIT",cmd[2]))
	{
		cm_demo_printf("ble cm_ble_deinit ret:%d\n", cm_ble_deinit());//去初始化ble，关闭BLE协议栈
	}else if(0 == strcmp("GET_STATE",cmd[2]))
	{
		cm_ble_status_e status =-1;
		cm_demo_printf("ble cm_ble_get_state ret:%d\n", cm_ble_get_state(&status));//查询BLE当前状态
		cm_demo_printf("state:%d\n",status);
	}
	else if(0 == strcmp("GET_ADDR",cmd[2]))
	{
		const cm_ble_addr_e type = atoi(cmd[3]);
		char addr[50] = {0};
		cm_demo_printf("ble cm_ble_get_addr ret:%d\n", cm_ble_get_addr(type,addr));//读取BLE设备地址
		cm_demo_printf("ble addr:%02X%s%02X%s%02X%s%02X%s%02X%s%02X\n",addr[0], ":", addr[1], ":", addr[2], ":", addr[3], ":", addr[4], ":", addr[5]);
	}else if(0 == strcmp("SET_NAME",cmd[2]))
	{
		char name[100] = {0};
		uint8_t len = 0;
		char set_name[100] = {0};
		strcpy(set_name,cmd[3]);
		uint8_t set_len = strtoul(cmd[4],(void*)0,10);
		len = set_len;
		cm_demo_printf("name:%s, len:%d\n",set_name,set_len);
		cm_demo_printf("cm_ble_get_name ret:%d\n", cm_ble_get_name(name, &len));//查询BLE设备名称
		cm_demo_printf("len:%d,name:%s\n",len,name);
		cm_demo_printf("cm_ble_set_name ret:%d\n", cm_ble_set_name(set_name,set_len));//设置BLE设备名称
		cm_demo_printf("cm_ble_get_name ret:%d\n", cm_ble_get_name(name, &len));
		cm_demo_printf("len:%d,name:%s\n",len,name);
		osDelay(5);
	}else if(0 == strcmp("WHITELIST",cmd[2]))
	{
		if(0 == strcmp("SET",cmd[3]))
		{
			cm_ble_addr_t addr = {
				.type = atoi(cmd[4]),
				.addr = {strtoul(cmd[5],(void*)0,16),strtoul(cmd[6],(void*)0,16),strtoul(cmd[7],(void*)0,16),strtoul(cmd[8],(void*)0,16),strtoul(cmd[9],(void*)0,16),strtoul(cmd[10],(void*)0,16)},
			};
			cm_demo_printf("cm_ble_set_whitelist ret:%d\n",cm_ble_set_whitelist(&addr));//设置白名单
			uint8_t write_size = 0;
			uint8_t total_size = 0;
			cm_demo_printf("cm_ble_get_whitelist_size ret:%d\n", cm_ble_get_whitelist_size(&write_size, &total_size));//获取白名单设置信息大小
			cm_demo_printf("write_size:%d,total_size:%d\n",write_size,total_size);
		}
		if(0 == strcmp("GET",cmd[3]))
		{
			cm_ble_addr_t get_addr[12] = {0};
			uint8_t get_len = 0;
			cm_demo_printf("cm_ble_get_whitelist ret:%d\n",cm_ble_get_whitelist(get_addr ,&get_len));//获取白名单地址
			for(int i = 0;i<get_len;++i)
			{
				cm_demo_printf("cm_ble_get_whitelist-%d: %02X%s%02X%s%02X%s%02X%s%02X%s%02X\n", i,get_addr[i].addr[0], ":", get_addr[i].addr[1], ":", get_addr[i].addr[2], ":", get_addr[i].addr[3], ":", get_addr[i].addr[4], ":", get_addr[i].addr[5]);
			}
		}
		if(0 == strcmp("DEL",cmd[3]))
		{
			uint8_t mode = atoi(cmd[4]);
			cm_ble_addr_t addr = {
				.type = CM_BLE_ADDR_PUBLIC,
				.addr = {strtoul(cmd[5],(void*)0,16),strtoul(cmd[6],(void*)0,16),strtoul(cmd[7],(void*)0,16),strtoul(cmd[8],(void*)0,16),strtoul(cmd[9],(void*)0,16),strtoul(cmd[10],(void*)0,16)}
			};
			cm_demo_printf("cm_ble_del_whitelist ret:%d\n", cm_ble_del_whitelist(mode, &addr));//删除/清空白名单
		}
	}
	else if(0 == strcmp("CLIENT",cmd[2]))
	{
		if(0 == strcmp("SCAN_ENABLE",cmd[3]))
		{
			cm_ble_scan_cfg_t scan_cfg = {
				.addr_type = atoi(cmd[4]),
				.filter_policy = atoi(cmd[5]),
				.scan_interval = atoi(cmd[6]),
				.scan_mode = atoi(cmd[7]),
				.scan_time = atoi(cmd[8]),
				.scan_window = atoi(cmd[9]),
			};
			cm_demo_printf("cm_ble_scan_cfg ret:%d\n", cm_ble_scan_cfg(&scan_cfg));//client端设置BLE扫描功能相关参数
			cm_demo_printf("cm_ble_scan_enable ret:%d\n",  cm_ble_scan_enable());//使能BLE扫描
		}
		else if(0 == strcmp("SCAN_DISABLE",cmd[3]))
		{
			cm_demo_printf("cm_ble_scan_disable ret:%d\n",  cm_ble_scan_disable());//关闭BLE扫描
		}
		else if(0 == strcmp("CONNECT",cmd[3]))
		{
			cm_ble_connect_cfg_t con_cfg = {
				.conn_index = atoi(cmd[4]),
				.latency = 50,
				.max_interval = 3200,
				.min_interval = 6,
				.peer_addr = 
				{
					.addr = {strtoul(cmd[5],(void*)0,16),strtoul(cmd[6],(void*)0,16),strtoul(cmd[7],(void*)0,16),strtoul(cmd[8],(void*)0,16),strtoul(cmd[9],(void*)0,16),strtoul(cmd[10],(void*)0,16)},
					.type = atoi(cmd[11]),
				},
				.timeout = 100,
			};
			cm_demo_printf("cm_ble_client_connect ret:%d\n", cm_ble_client_connect(&con_cfg));
		}
		else if(0 == strcmp("DISCONNECT",cmd[3]))
		{
			uint8_t index = atoi(cmd[4]);
			cm_demo_printf("cm_ble_diconnect ret:%d\n",cm_ble_diconnect(index));
		}
		else if(0 == strcmp("FIND_SERVER",cmd[3]))
		{
			uint8_t index = atoi(cmd[4]);
			uint16_t srv_id = atoi(cmd[5]);
			uint16_t chr_id = atoi(cmd[6]);
			cm_ble_uuid_t srv_uuid = {
				.uuid_type = CM_BLE_UUID_TYPE_16_BIT,
				.uuid = {0x28,0x00},
			};
			cm_demo_printf("cm_ble_gattc_find_service ret:%d\n",cm_ble_gattc_find_service(index));
			osDelay(50);
			cm_demo_printf("cm_ble_gattc_find_service_uuid ret:%d\n",cm_ble_gattc_find_service_uuid(index,&srv_uuid));
			osDelay(50);
			cm_demo_printf("cm_ble_gattc_find_character ret:%d\n",cm_ble_gattc_find_character(index,srv_id));
			osDelay(50);
			cm_demo_printf("cm_ble_gattc_find_descriptor ret:%d\n",cm_ble_gattc_find_descriptor(index,srv_id,chr_id));
		}
		else if(0 == strcmp("RDWR_CHR_DES",cmd[3]))
		{
			uint8_t index = atoi(cmd[4]);
			uint16_t srv_id = atoi(cmd[5]);
			uint16_t chr_id = atoi(cmd[6]);
			uint32_t des_id = atoi(cmd[7]);
			uint16_t length = 10;
			char data[10] = {atoi(cmd[8]),0x34,0x56,0x78,0x90,0x21,0x43,0x65,0x87,0x09};
			cm_demo_printf("cm_ble_gattc_read ret:%d\n",cm_ble_gattc_read(index,srv_id,chr_id,des_id));
			osDelay(50);
			cm_demo_printf("cm_ble_gattc_write ret:%d\n",cm_ble_gattc_write(index,srv_id,chr_id,des_id,length,data));
		}
	}
	else if(0 == strcmp("SERVER",cmd[2]))
	{
		if(0 == strcmp("ADV_ENABLE",cmd[3]))
		{
			cm_ble_adv_cfg_t adv_cfg =
			{
				.b_int_min = 128,
				.b_int_max = 160,
				.boardcast_type = atoi(cmd[4]),		
				.addr_type = atoi(cmd[5]),
				.b_ch = CM_BLE_ADV_CH37|CM_BLE_ADV_CH38|CM_BLE_ADV_CH39,
				.b_filter = atoi(cmd[6]),
				.b_duration = 0,
			};
			cm_demo_printf("cm_ble_set_adv_data ret:%d\n", cm_ble_set_adv_param(&adv_cfg));//BLE广播功能相关参数（server端）。
			cm_ble_adv_data_t adv_data =
			{
				.adv_data = {0x0a,0x09,0x4f,0x6e,0x65,0x4d,0x4f,0x5f,0x42,0x4c,0x45}, //设置广播 
				.adv_len = 11,
				.scan_ack_data = {0x0a,0x09,0x4f,0x6e,0x65,0x4d,0x4f,0x5f,0x42,0x4c,0x45}, // 设 置 扫 描 响 应
				.scan_ack_len = 11,
			};
			cm_demo_printf("cm_ble_set_adv_data ret:%d\n", cm_ble_set_adv_data(&adv_data));//BLE设置广播内容（server端）。
			cm_demo_printf("cm_ble_adv_enable ret:%d\n", cm_ble_adv_enable());//使能BLE广播
		}
		else if(0 == strcmp("ADV_DISABLE",cmd[3]))
		{
			cm_demo_printf("cm_ble_adv_disable ret:%d\n",  cm_ble_adv_disable());//关闭BLE广播
		}
		else if(0 == strcmp("CONNECT_PARA_UPDATE",cmd[3]))
		{
			cm_ble_connect_cfg_t con_cfg = {
			.conn_index = atoi(cmd[4]),
			.latency = 5,
			.max_interval = 480,
			.min_interval = 480,
			.peer_addr = 
			{
				.addr = {strtoul(cmd[5],(void*)0,16),strtoul(cmd[6],(void*)0,16),strtoul(cmd[7],(void*)0,16),strtoul(cmd[8],(void*)0,16),strtoul(cmd[9],(void*)0,16),strtoul(cmd[10],(void*)0,16)},
				.type = atoi(cmd[11]),
			},
			.timeout = atoi(cmd[12]),
			};
			cm_demo_printf("cm_ble_connect_para_update ret:%d\n", cm_ble_connect_para_update(&con_cfg));//更新BLE连接参数

		}
		else if(0 == strcmp("ADD_SERVER_START",cmd[3]))
		{
			uint16_t srv_id = 0;
			cm_ble_uuid_t srv_uuid = {
				.uuid_type = CM_BLE_UUID_TYPE_16_BIT,
				.uuid =  {0x28,0x00},
			};
			uint8_t srv_type = 1;
			uint32_t inc_srv_id = 0xffffffff;
			uint32_t chr_id = 0;
			cm_ble_uuid_t chr_uuid = {
				.uuid_type = CM_BLE_UUID_TYPE_16_BIT,
				.uuid =  {0x2A,0x4D},
			};
			cm_demo_printf("cm_ble_gatts_add_service ret:%d\n", cm_ble_gatts_add_service(srv_id, &srv_uuid,srv_type, inc_srv_id));
			uint16_t length = 10;
			char val[10] = {0x1A,0x24,0x00,0x4D,0x2A,0x11,0x56,0x55,0xaa,0xef};
			cm_demo_printf("cm_ble_gatts_add_character 1 ret:%d\n",cm_ble_gatts_add_character(srv_id, chr_id,&chr_uuid,CM_BLE_GATT_CHARACTER_PROPERTY_BIT_INDICATE|CM_BLE_GATT_CHARACTER_PROPERTY_BIT_NOTIFY|CM_BLE_GATT_CHARACTER_PROPERTY_BIT_WRITE | CM_BLE_GATT_CHARACTER_PROPERTY_BIT_READ,length,val));
			chr_uuid.uuid[0] = 0x2A;
			chr_uuid.uuid[1] = 0x09;
			val[0] = 0x09;
			val[9] = 0xfe;
			chr_id = 1;
			cm_demo_printf("cm_ble_gatts_add_character 2 ret:%d\n",cm_ble_gatts_add_character(srv_id, chr_id,&chr_uuid,CM_BLE_GATT_CHARACTER_PROPERTY_BIT_INDICATE|CM_BLE_GATT_CHARACTER_PROPERTY_BIT_NOTIFY|CM_BLE_GATT_CHARACTER_PROPERTY_BIT_WRITE | CM_BLE_GATT_CHARACTER_PROPERTY_BIT_READ,length,val));
			uint16_t des_id = 0;
			cm_ble_uuid_t desc_uuid = {
				.uuid_type = CM_BLE_UUID_TYPE_16_BIT,
				.uuid = {0x29,0x02},
			};
			val[2] = 0x00;
			val[3] = 0x00;
			uint16_t des_permission = CM_BLE_GATT_PERMISSION_READ | CM_BLE_GATT_PERMISSION_WRITE;
			cm_demo_printf("cm_ble_gatts_add_descriptor ret:%d\n",cm_ble_gatts_add_descriptor(srv_id, chr_id,des_id,&desc_uuid,des_permission,length,val));
			chr_id = 0;
			desc_uuid.uuid[1] = 0x03;
			val[2] = 0xCD;
			val[3] = 0xEF;
			cm_demo_printf("cm_ble_gatts_add_descriptor ret:%d\n",cm_ble_gatts_add_descriptor(srv_id, chr_id,des_id,&desc_uuid,des_permission,length,val));
			cm_demo_printf("cm_ble_gatts_start ret:%d\n",cm_ble_gatts_start(srv_id));
		}
		else if(0 == strcmp("STOP",cmd[3]))
		{			
			uint16_t srv_id = atoi(cmd[4]);
			//cm_demo_printf("cm_ble_gatts_stop",cm_ble_gatts_stop(&srv_id));
		}
		else if(0 == strcmp("GATTS_OP",cmd[3]))
		{
			uint16_t srv_id = atoi(cmd[5]);
			uint16_t chr_id = atoi(cmd[6]);
			uint32_t des_id = atoi(cmd[7]);
			uint16_t length = atoi(cmd[8]);
			char data[10] = {atoi(cmd[9]),0x34,0x56,0x78,0x90,0x21,0x43,0x65,0x87,0x09};
			if(0 == strcmp("WRITE",cmd[4]))
			{
				cm_demo_printf("cm_ble_gatts_write ret:%d\n",cm_ble_gatts_write(srv_id,chr_id,des_id,length,data));
			}
			if(0 == strcmp("READ",cmd[4]))
			{
				data[0] = 0;
				cm_demo_printf("cm_ble_gatts_read ret:%d\n",cm_ble_gatts_read(srv_id,chr_id,des_id,&length,data));
				cm_demo_printf("read len:%d,data:%d",length,data[0]);
			}
			if(0 == strcmp("NOTIFY",cmd[4]))
			{
				uint8_t index = atoi(cmd[7]);
				cm_demo_printf("cm_ble_gatts_notify ret:%d\n", cm_ble_gatts_notify(index,srv_id,chr_id,length,data));
			}
			if(0 == strcmp("INDICATION",cmd[4]))
			{
				uint8_t index = atoi(cmd[7]);
				cm_demo_printf("cm_ble_gatts_indication ret:%d\n", cm_ble_gatts_indication(index,srv_id,chr_id,length,data));
			}
		}
	}	
	else
	{
		cm_demo_printf("param error!\n");
	}
}

